import React from 'react';
import { Button, message, Icon } from 'antd';
import styles from './index.less';
import { connect } from 'dva';
import { getStageBydialogIdAndNodeId, getActionNodeDetail, knowledgeDialogActionNodeInfo, knowledgeDialogNodeInfo } from '@/services/dialog';
import UserSession from "@/UserSession";

@connect(({ DialogAdd, loading }) => ({
  DialogAdd,
  loading: loading.effects['dialogAdd/fetchSlot'],
}))
class Save extends React.Component {
  state = {
    saveLoading: false,
    publishLoading: false,
    tranLoading: false,
  };

  /** 保存 **/
  handleClick = () => {
    const { graphObj, dialogId } = this.props;

    // let resObj = graphObj.graph.save();
    // let { nodes } = resObj;
    //
    // nodes.forEach(node => {
    //   node.size = node.width + '*' + node.height;
    //   delete node.style;
    //   delete node.labelCfg;
    // });
    let cells = graphObj.toJSON().cells;
    console.log(cells);
    let nodes = [];
    let edges = [];
    for (const cellItem of cells) {
      if (cellItem.shape === 'edge') {
        edges.push(cellItem);
      } else {
        nodes.push(cellItem);
      }
    }
    //处理node
    const nodeAfterSet = [];
    for (let node of nodes) {
      let obj = {
        id: node.id.split('-')[0],
        nodeId: node.id.split('-')[0],
        size: node.size.width + '*' + node.size.height,
        modal: node.attrs.text.text,
        label: node.attrs.text.textWrap.text,
        width: node.size.width,
        height: node.size.height,
        x: node.position.x,
        y: node.position.y,
        shape: node.shape,
      };
      nodeAfterSet.push(obj);
      // node.id = node.id.split('-')[0];
      // node.nodeId = node.id.split('-')[0];
      // node.size = node.size.width + '*' + node.size.height;
      // node.modal = node.attrs.text.text;
      // node.label = node.attrs.text.textWrap.text;
      // node.width = node.size.width;
      // node.height = node.size.height;
      // node.x = node.position.x;
      // node.y = node.position.y;
      // delete node.attrs;
      // delete node.markup;
      // delete node.ports.groups
      // delete node.position
      // node.des = JSON.stringify(node)
      console.log(node, obj);
    }

    //处理edge
    const edgesAfterSet = [];
    for (let edge of edges) {
      let obj = {
        id: edge.id.split('-')[0],
        source: edge.source.cell.split('-')[0],
        sourceAnchor: parseInt(edge.source.port),
        target: edge.target.cell.split('-')[0],
        targetAnchor: parseInt(edge.target.port),
        shape: edge.shape,
      };
      edgesAfterSet.push(obj);
      console.log(edge, obj);
    }

    this.setState({ saveLoading: true }, () => {
      this.save({ nodes: nodeAfterSet, edges: edgesAfterSet }, dialogId);
    });
  };

  save = (data, dialogId) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'dialogAdd/saveDialog',
      payload: {
        dialogId,
        data,
      },
      callback: res => {
        message.info(res.msg);
        this.setState({ saveLoading: false });
      },
    });
  };

  /** 训练 **/
  trainDialog = () => {
    const { dispatch, dialogId } = this.props;
    if (this.checkGaphData().status) {
      this.setState({ tranLoading: true }, () => {
        this.judgeNodeData('train');
      });
    } else {
      return message.error(this.checkGaphData().msg);
    }
  };

  doTraining = () => {
    const { dispatch, dialogId } = this.props;
    dispatch({
      type: 'dialogAdd/trainDialog',
      payload: {
        dialogId,
      },
      callback: res => {
        this.setState({ tranLoading: false }, () => {
          if (!res.code && typeof res === 'object') {
            this.props.showTrain();
          }
        });
      },
    });
  };

  /** 发布 **/
  publishDialog = () => {
    const { dispatch, dialogId } = this.props;
    if (this.checkGaphData().status) {
      this.setState({ publishLoading: true }, () => {
        this.judgeNodeData('publish');
      });
    } else {
      return message.error(this.checkGaphData().msg);
    }
  };

  doPublishing = () => {
    const { dispatch, dialogId } = this.props;
    dispatch({
      type: 'dialogAdd/publishDialog',
      payload: {
        dialogId,
      },
      callback: res => {
        this.setState({ publishLoading: false }, () => {
          if (!res.code) {
            message.info(res.msg);
            this.props.getStatusById();
          }
        });
      },
    });
  };

  /** 【节点-连线校验】 **/
  checkGaphData = () => {
    const { graphObj, dialogId, dispatch } = this.props;
    const { cells } = graphObj.toJSON();
    const nodesArr = [];
    // eslint-disable-next-line no-restricted-syntax
    for (const cellItem of cells) {
      if (cellItem.shape !== 'edge') {
        nodesArr.push(cellItem);
      }
    }
    // 处理node
    // eslint-disable-next-line no-restricted-syntax
    const resArr = [];

    // 判断是否包含结束节点
    if (!nodesArr.some(item => item.attrs.text.text === 'end')) {
      return {
        status: false,
        msg: '缺少结束节点，请添加后再尝试',
      };
    }

    if (!nodesArr.some(item => item.attrs.text.text === 'start')) {
      return {
        status: false,
        msg: '缺少开始节点，请添加后再尝试',
      };
    }

    //判断节点
    const edges = graphObj.getEdges();
    for (const nodeItem of nodesArr) {
      //判断节点非开始/结束节点 是否有接收端和输出端
      if (
        nodeItem.attrs.text.text !== 'start' &&
        nodeItem.attrs.text.text !== 'end' &&
        !edges.some(item => item.getTarget().cell === nodeItem.id)
      ) {
        return {
          status: false,
          msg: nodeItem.attrs.text.textWrap.text + '节点，缺少接收端',
        };
      } else if (
        nodeItem.attrs.text.text !== 'start' &&
        nodeItem.attrs.text.text !== 'end' &&
        !edges.some(item => item.getSource().cell === nodeItem.id)
      ) {
        return {
          status: false,
          msg: nodeItem.attrs.text.textWrap.text + '节点，缺少输出端',
        };
      } else if (
        nodeItem.attrs.text.text === 'start' &&
        !edges.some(item => item.getSource().cell === nodeItem.id)
      ) {
        return {
          status: false,
          msg: nodeItem.attrs.text.textWrap.text + '节点，缺少输出端',
        };
      } else if (
        nodeItem.attrs.text.text === 'end' &&
        !edges.some(item => item.getTarget().cell === nodeItem.id)
      ) {
        return {
          status: false,
          msg: nodeItem.attrs.text.textWrap.text + '节点，缺少接收端',
        };
      }
    }

    // 判断是否有多个子图
    for (const node of nodesArr) {
      const edgeList = graphObj.getConnectedEdges(node);
      // 不是开始节点且输入和输出边小于2
      if (
        node.attrs.text.text !== 'start' &&
        node.attrs.text.text !== 'end' &&
        edgeList.length < 2
      ) {
        resArr.push({ type: node.attrs.text.text, edgeLength: edgeList.length });
      } else if (node.attrs.text.text === 'end' && edgeList.length < 1) {
        resArr.push({ type: node.attrs.text.text, edgeLength: edgeList.length });
      }
    }

    if (resArr.length) {
      return {
        status: false,
        msg: '当前存在多个子图，一个多轮只支持一个子图，请修改后再尝试',
      };
    }
    return {
      status: true,
      msg: '',
    };
  };

  /**
   * 获取数据【节点-数据校验】
   */
  judgeNodeData = async type => {
    const { graphObj, dialogId, dispatch } = this.props;
    const nodes = graphObj.getNodes();

    //判断开始节点的数据
    const startNode = nodes.filter(item => item.getAttrs().text.text === 'start');
    for (const node of startNode) {
      const nodeId = node.id.split('-')[0];
      let res = null;
      if (UserSession.isSystemKnowledge()) {
        res = await knowledgeDialogNodeInfo({
          nodeType: 'start',
          dialogId: dialogId,
          nodeId,
          field: '',
        })
      } else {
        res = await getStageBydialogIdAndNodeId({
          stage: 'start',
          dialogId: dialogId,
          nodeId,
          field: '',
        });
      }
      const questions = !res.dialogStage.data.questions ? [] : res.dialogStage.data.questions;
      if (questions.length === 0) {
        message.error(node.getAttrs().text.textWrap.text + '节点,缺少相似问题，补充后再重试');
        this.closeLoading(type);
        return false;
      }
    }

    //判断收集词槽的数据
    const slotNode = nodes.filter(item => item.getAttrs().text.text === 'slot');
    for (const node of slotNode) {
      const nodeId = node.id.split('-')[0];
      let res = null;
      if (UserSession.isSystemKnowledge()) {
        res = await knowledgeDialogNodeInfo({
          nodeType: 'slot',
          dialogId: dialogId,
          nodeId,
          field: '',
        })
      } else {
        res = await getStageBydialogIdAndNodeId({
          stage: 'slot',
          dialogId: dialogId,
          nodeId,
          field: '',
        });
      }
      const inquire = res.dialogStage.inquire;
      if (!inquire || !inquire.slots || (inquire.slots && inquire.slots.length === 0)) {
        message.error(
          node.getAttrs().text.textWrap.text + '节点,词槽询问，需要添加要收集的词槽，请补充后再重试'
        );
        this.closeLoading(type);
        return false;
      }
    }

    //判断信息确认的数据
    const confirmNode = nodes.filter(item => item.getAttrs().text.text === 'confirm');
    for (const node of confirmNode) {
      const nodeId = node.id.split('-')[0];
      let res = null;
      if (UserSession.isSystemKnowledge()) {
        res = await knowledgeDialogNodeInfo({
          nodeType: 'confirm',
          dialogId: dialogId,
          nodeId,
          field: 'setting',
        })
      } else {
        res = await getStageBydialogIdAndNodeId({
          stage: 'confirm',
          dialogId: dialogId,
          nodeId,
          field: 'setting',
        });
      }
      const setting = res.dialogStage.setting;
      if (!setting || !setting.resultTitle) {
        message.error(
          node.getAttrs().text.textWrap.text +
            '节点,信息确认设置，需要添加信息确认话术，请补充后再重试'
        );
        this.closeLoading(type);
        return false;
      }
      if (!setting || !setting.resultTemplate) {
        message.error(
          node.getAttrs().text.textWrap.text +
            '节点,信息确认设置，需要添加信息展示模版，请补充后再重试'
        );
        this.closeLoading(type);
        return false;
      }
    }

    //判断内容筛选的数据
    const filterNode = nodes.filter(item => item.getAttrs().text.text === 'filter');
    for (const node of filterNode) {
      const nodeId = node.id.split('-')[0];
      let res = null;
      if (UserSession.isSystemKnowledge()) {
        res = await knowledgeDialogNodeInfo({
          nodeType: 'filter',
          dialogId: dialogId,
          nodeId,
          field: '',
        })
      } else {
        res = await getStageBydialogIdAndNodeId({
          stage: 'filter',
          dialogId: dialogId,
          nodeId,
          field: '',
        });
      }
      const setting = res.dialogStage.settings;
      let isEmptySetting = Object.keys(setting);
      if (!setting || isEmptySetting.length === 0 || !setting.apiId) {
        message.error(
          node.getAttrs().text.textWrap.text + '节点,筛选设置，需要添加API接口，请补充后再重试'
        );
        this.closeLoading(type);
        return false;
      }
      if (!setting.mapping || setting.mapping.length === 0) {
        message.error(
          node.getAttrs().text.textWrap.text +
            '节点,筛选设置，需要添加词槽与API的对应关系，请补充后再重试'
        );
        this.closeLoading(type);
        return false;
      }
      if (!setting.uniqueSlot) {
        message.error(
          node.getAttrs().text.textWrap.text + '节点,筛选设置，需要添加唯一性词槽，请补充后再重试'
        );
        this.closeLoading(type);
        return false;
      }
      if (!setting.resultTemplate) {
        message.error(
          node.getAttrs().text.textWrap.text +
            '节点,筛选设置，结果展示模版，需要添加 结果展示话术，请补充后再重试'
        );
        this.closeLoading(type);
        return false;
      }
    }

    //判断触发条件的数据
    const caseNode = nodes.filter(item => item.getAttrs().text.text === 'case');
    for (const node of caseNode) {
      const nodeId = node.id.split('-')[0];
      let res = null;
      if (UserSession.isSystemKnowledge()) {
        res = await knowledgeDialogNodeInfo({
          nodeType: 'case',
          dialogId: dialogId,
          nodeId,
          field: 'data',
        })
      } else {
        res = await getStageBydialogIdAndNodeId({
          stage: 'case',
          dialogId: dialogId,
          nodeId,
          field: 'data',
        });
      }
      const data = res.dialogStage.data;
      if (
        !data ||
        (data.caseType === 'slot' && data.caseItemGroups.length === 0) ||
        (data.caseType === 'user_reply' && data.replies.length === 0)
      ) {
        message.error(
          node.getAttrs().text.textWrap.text + '节点,需要至少填充一种触发条件类型，请补充后再重试'
        );
        this.closeLoading(type);
        return false;
      }
    }

    //判断动作模块的数据
    const actionNode = nodes.filter(item => item.getAttrs().text.text === 'action');
    for (const node of actionNode) {
      const nodeId = node.id.split('-')[0];
      let res = null;
      if (UserSession.isSystemKnowledge()) {
        res = await knowledgeDialogActionNodeInfo({ dialogId, nodeId });
      } else {
        res = await getActionNodeDetail({ dialogId, nodeId });
      };
      const isReply =
        ((!res.field || res.field === 'reply') && !res.reply) ||
        ((!res.field || res.field === 'reply') && !res?.reply?.content);
      const isApi = (res.field === 'api' && !res.api) || (res.field === 'api' && !res.api.apiId);
      const isClear = res.field === 'clear' && !res.clear;
      if (isReply || isApi || isClear) {
        message.error(
          node.getAttrs().text.textWrap.text +
            '节点,回复、调用API接口、清空词槽至少填充一种数据，请补充后再重试'
        );
        this.closeLoading(type);
        return false;
      }
    }

    /** ---调用【训练】或【发布】接口--- **/
    switch (type) {
      case 'train':
        this.doTraining();
        break;

      case 'publish':
        this.doPublishing();
        break;
    }
  };

  /** ---关闭【训练】或【发布】按钮的loading--- **/
  closeLoading = type => {
    switch (type) {
      case 'train':
        this.setState({ tranLoading: false });
        break;

      case 'publish':
        this.setState({ publishLoading: false });
        break;
    }
  };

  render() {
    const { saveLoading, publishLoading, tranLoading } = this.state;
    const { status } = this.props;
    return (
      <span className={styles.saveBtn} style={{ margin: 0, textAlign: 'right' }}>
        {/* <Button loading={tranLoading} onClick={() => this.trainDialog()}>训练</Button> */}
        {/* {status === 3 ? (
          <Button loading={publishLoading} style={{ margin: '0 10px' }} disabled>
            <Icon type="check" style={{ color: 'green' }} />
            已发布
          </Button>
        ) : (
          <Button
            loading={publishLoading}
            onClick={() => this.publishDialog()}
            style={{ margin: '0 10px' }}
            disabled={status !== 2}
          >
            发布
          </Button>
        )} */}
        <span>{this.props.publishTime ? `上次发布时间：${this.props.publishTime}` : ''}</span>
        {UserSession.isAdmin() ? null : (
          <Button loading={publishLoading} onClick={() => this.publishDialog()} style={{ margin: '0 10px' }} disabled={UserSession.whetherCanDelete()}>发布</Button>
        )}
        <Button loading={saveLoading} type="primary" onClick={this.handleClick} disabled={UserSession.whetherCanDelete()}>保存</Button>
      </span>
    );
  }
}

export default Save;
